/*
*  group.c - Group management functions
*  Copyright (c) 2005 Derek Ingrouville (dergro@users.sourceforge.net)
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Library General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdlib.h>
#include <string.h>

#include "group.h"
#include "utility.h"

MsnGroup *
msn_group_new ()
{
	MsnGroup *group;

	group = g_new (MsnGroup, 1);
	group->guid = NULL;
	group->name = NULL;
	group->contacts = NULL;
	group->num_contacts = 0;

	return group;
}

MsnGroup *
msn_group_from_lsg (MsnCommand *lsg)
{
	/* LSG grp_name grp_guid */
	MsnGroup *group;

	g_return_val_if_fail (lsg != NULL, NULL);
	g_return_val_if_fail (lsg->param_count > 0, NULL);

	/* Check if we have a valid LSG */
	if (strcmp (lsg->name, "LSG") != 0)
		return NULL;

	group = msn_group_new ();
	group->name = url_decode (lsg->params[0]);
	group->guid = strdup (lsg->params[1]);

	return group;
}

/* TODO: update adg */
MsnGroup *
msn_group_from_adg (MsnCommand *adg)
{
	/* ADG trid clist_ver group_name grp_id 0 */
	MsnGroup *group;

	g_return_val_if_fail (adg != NULL, NULL);
	g_return_val_if_fail (adg->param_count > 0, NULL);

	return NULL;
	/* Check if we have a valid ADG */
	/*if (strcmp (adg->name, "ADG") != 0)
		return NULL;

	group = msn_group_new ();
	group->id = atoi (adg->params[3]);
	group->name = url_decode (adg->params[2]);

	return group;*/
}

void
msn_group_free (MsnGroup *group)
{
	g_return_if_fail (group != NULL);

	if (group->name != NULL)
		g_free (group->name);
	
	if (group->guid != NULL)
		g_free (group->guid);

	if (group->contacts != NULL) {
		MsnContact *contact = NULL;
		GList *list = group->contacts;

		while (list != NULL) {
			contact = (MsnContact *) list->data;

			if (contact == NULL)
				break;

			msn_contact_free (contact);

			list = g_list_next (list);
		}

		g_list_free (group->contacts);
	}

	g_free (group);

	return;
}

int
msn_group_add_contact (MsnGroup *group, MsnContact *contact)
{
	MsnContact *tmp = NULL;

	g_return_val_if_fail (group != NULL, -1);
	g_return_val_if_fail (contact != NULL, -1);

	/* First check that the contact isn't already in the group */
	tmp = msn_group_find_contact_from_passport (group, contact->passport);
	if (tmp != NULL)
		return 0;

	if (g_list_length (contact->groups) > 1) {
		/* Need to reference the contact if it is in mutliple groups */
		msn_contact_ref (contact);
	}

	group->contacts = g_list_append (group->contacts, contact);
	group->num_contacts++;

	return 0;
}

int
msn_group_remove_contact (MsnGroup *group, MsnContact *contact)
{
	g_return_val_if_fail (group != NULL, -1);
	g_return_val_if_fail (contact != NULL, -1);

	group->contacts = g_list_remove (group->contacts, contact);
	group->num_contacts--;
	msn_contact_free (contact);

	return 0;
}

int
contact_has_passport (gconstpointer data, gconstpointer passport)
{
	MsnContact *contact;

	g_return_val_if_fail (data != NULL, -1);
	g_return_val_if_fail (passport != NULL, -1);

	contact = (MsnContact *) data;

	return -1;
}

MsnContact *
msn_group_find_contact_from_passport (MsnGroup *group, const char *passport)
{
	GList *list = NULL;
	MsnContact *contact = NULL;

	g_return_val_if_fail (group != NULL, NULL);
	g_return_val_if_fail (passport != NULL, NULL);

	list = group->contacts;
	g_print ("searching for passport: %s\n", passport);

	while (list != NULL) {
		MsnContact *tmp = (MsnContact *) list->data;

		if (tmp == NULL)
			break;

		g_print ("current: %s\n", tmp->passport);
		if (strcmp (tmp->passport, passport) == 0) {
			contact = tmp;
			break;
		}

		list = g_list_next (list);
	}

	return contact;
}

unsigned int
msn_group_get_num_contacts_online (MsnGroup *group)
{
	GList *list = NULL;
	unsigned int online = 0;

	g_return_val_if_fail (group != NULL, 0);

	list = group->contacts;

	while (list != NULL) {
		MsnContact *contact = (MsnContact *) list->data;

		if (contact == NULL)
			break;

		if (contact->status != OFFLINE)
			online++;

		list = g_list_next (list);
	}

	return online;
}
